package com.wthink.hzgj.main.viewmodel

import android.speech.tts.TextToSpeech
import android.util.Log
import android.widget.TableRow
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.wthink.hzgj.BusApplication
import com.wthink.hzgj.data.Result
import com.wthink.hzgj.data.domain.*
import com.wthink.hzgj.service.DevService
import com.wthink.hzgj.service.ScreenProvider
import com.wthink.hzgj.util.PreferencesUtils
import com.wthink.hzgj.util.`interface`.NoticeCallBack
import com.wthink.hzgj.util.toast
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.collect
import java.math.BigDecimal
import java.net.URLDecoder
import java.net.URLEncoder
import java.nio.charset.Charset
import java.text.SimpleDateFormat
import java.util.*


class MainViewModel : ViewModel() {

    var mix = 0L

    val now = MutableLiveData("")
    val devState = MutableLiveData(DevState(false, false, false))
    val busState = MutableLiveData(BusStateA("", "", "", "", true,""))
    val gpsState = MutableLiveData(Location(0.0, 0.0, 0))
    val faced = MutableLiveData(FaceRec(""))

    val showCamera = MutableLiveData(false)

    val scrollText = MutableLiveData("")


    fun start() {

        getCurrentTime()
        viewModelScope.launch(Dispatchers.IO) {
            val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
            while (isActive) {
                val nowTime: BigDecimal =
                    BigDecimal(mix).add(BigDecimal(System.currentTimeMillis()))
                now.postValue(sdf.format(nowTime))
                delay(200)
            }
        }

        scrollText.postValue("暴雨天气，请减速慢行！")

        queryDevStateUntilSuccess()
        waitDevState()

        queryBusStateUntilSuccess()
        waitBusState()

        queryGps()
        waitGps()

        waitBusNotice()

        waitFaceState()

        waitUsbState()

    }

    private fun getCurrentTime(delay: Long = 1000 * 10) {
        viewModelScope.launch(Dispatchers.IO) {
            while (isActive) {
                val ret = DevService.getTime()
                if (ret is Result.Success) {
                    val data = ret.data * 1000
                    mix = data - System.currentTimeMillis() + 1000 * 60 * 60 * 8
                    PreferencesUtils.saveValue("mix", mix)
                    val long = PreferencesUtils.getLong("mix")
                }
                delay(delay)
            }
        }
    }

    fun isCameraShow(): Boolean {
        return showCamera.value!!
    }

    fun cameraSwitchAndGet(): Boolean {
        val current = !showCamera.value!!
        showCamera.postValue(current)
        return current
    }

    fun queryGps() {
        viewModelScope.launch(Dispatchers.IO) {
            while (isActive) {
                val ret = DevService.queryGps()
                if (ret is Result.Success) {
                    gpsState.postValue(ret.data)
                    if (ret.data.speed > 60) {
                    }
                }
                delay(1000)
            }
        }
    }

    fun waitGps() {
        viewModelScope.launch(Dispatchers.IO) {
            DevService.listenGps().collect {
                gpsState.postValue(it)

            }
        }
    }

    fun queryDevStateUntilSuccess(delay: Long = 30000) {
        viewModelScope.launch(Dispatchers.IO) {
            while (isActive) {
                val ret = DevService.queryDevState()
                if (ret is Result.Success) {
                    devState.postValue(ret.data)
                } else if (ret is Result.Error) {
                    devState.postValue(DevState(false, false, false))
                }
                delay(delay)
            }
        }
    }

    fun waitDevState() {
        viewModelScope.launch(Dispatchers.IO) {
            DevService.listenDevState().collect {
                devState.postValue(it)
            }
        }
    }

    fun queryBusStateUntilSuccess(delay: Long = 30000) {
        viewModelScope.launch(Dispatchers.IO) {
            while (isActive) {
                val ret = DevService.queryBusState()
                if (ret is Result.Success) {
                    busState.postValue(ret.data)
                }
                delay(delay)
            }
        }
    }

    fun waitBusState() {
        viewModelScope.launch(Dispatchers.IO) {
            DevService.listenBusState().collect {
                //busState.postValue(it)
            }
        }
    }

    fun waitFaceState() {
        viewModelScope.launch(Dispatchers.IO) {
            DevService.listenFace().collect {
                val faced1 = it.isFaced
                Log.d("faceddddd", faced1)
                faced.postValue(it)
            }
        }
    }

    fun waitUsbState() {
        viewModelScope.launch(Dispatchers.IO) {
            DevService.listenUsb().collect {
                val usBadded = it.isUSBadded
                Log.d("usBadded", usBadded)
                withContext(Dispatchers.Main) {
                    if (usBadded == "add") {
                        toast(BusApplication.busContext, "usb已插入")
                    } else if (usBadded == "remove") {
                        toast(BusApplication.busContext, "usb已弹出")
                    }
                }
            }
        }
    }

    fun waitBusNotice() {
        viewModelScope.launch(Dispatchers.IO) {
            DevService.listenBusNotice().collect {
                val notice = it.notice
                Log.d("noticenotice", "notice->" + notice)
                saveNoticeAsList(notice)
                scrollText.postValue(notice)
                nocticeCallBack.noticeCall(notice)
            }
        }
    }

    private fun saveNoticeAsList(notice: String) {
        val noticeList = PreferencesUtils.stringToList()
        val spTime = PreferencesUtils.getSpTime()
        val noticeMsg = NoticeMsg(notice, spTime, "" + (noticeList.size + 1), false,false)
        noticeList.add(noticeMsg)
        PreferencesUtils.saveListToString(noticeList)
    }

    lateinit var nocticeCallBack: NoticeCallBack

    fun setNociceCallBack(callBack: NoticeCallBack) {
        nocticeCallBack = callBack
    }

    fun waitBusDispatch(cb: (busDispatch: BusDispatch) -> Unit) {
        viewModelScope.launch(Dispatchers.IO) {
            DevService.listenBusDispatch().collect {
                cb(it)
                if (it.ywlx == 1) {//1:上行
                    busState.postValue(
                        BusStateA(
                            it.line,
                            it.lineName,
                            "${it.startStationId}",
                            it.startStationName,
                            true,""
                        )
                    )
                } else {//2：下行，3：环行
                    busState.postValue(
                        BusStateA(
                            it.line,
                            it.lineName,
                            "${it.endStationId}",
                            it.endStationName,
                            false,""
                        )
                    )
                }
            }
        }
    }

    fun waitBusCameraCtl(onShow: () -> Unit, onClose: () -> Unit) {
        viewModelScope.launch(Dispatchers.IO) {
            ScreenProvider.cameraCtlFlow.collect {
                when (it) {
                    "show_camera" -> {
                        onShow()
                    }
                    "close_camera" -> {
                        onClose()
                    }
                }
            }
        }
    }

    var changeMicCallBack : ChangeMicCallBack? = null

    fun setCallBack(callBack: ChangeMicCallBack){
        changeMicCallBack = callBack
    }

    interface ChangeMicCallBack{
        fun callBack(type: Int)
    }

    fun changeMicModel(type: Int) {
        viewModelScope.launch(Dispatchers.IO) {
            val micInfo = DevService.changeMicModel(type)
            if (micInfo is Result.Success) {

                withContext(Dispatchers.Main) {
                    toast(BusApplication.busContext, "切换音频成功")
                }
            }
        }
    }

    fun closeMic(type: Int) {
        viewModelScope.launch(Dispatchers.IO) {
            val micInfo = DevService.closeMic(type)
            if (micInfo is Result.Success) {
                withContext(Dispatchers.Main) {
                    toast(BusApplication.busContext, "关闭音频成功")
                }
            }
        }
    }

    fun closeMicCall(type: Int) {
        viewModelScope.launch(Dispatchers.IO) {
            val micInfo = DevService.closeMic(type)
            if (micInfo is Result.Success) {
                changeMicCallBack?.callBack(type)
                withContext(Dispatchers.Main) {
                    toast(BusApplication.busContext, "关闭音频成功")
                }
            }
        }
    }

    fun setVoice(type: Int) {
        viewModelScope.launch(Dispatchers.IO){
            val serviceAudio = DevService.setServiceAudio(type)
            if (serviceAudio is Result.Success) {

            }
        }
    }
}